Monsterrhino Motion is an independent stepper motor controller.
It can run up to 4 stepper motors at once - in parallel. The powerful MCU combined with our advanced firmware (multitasking capable - up to 6 user tasks) allows you to control stepper motors in the most simple way - you can program it with the Arduino IDE or with more advanced IDEs. Our firmware allows you to program the card at a high level e.g. you tell the motor to rotate continuously, make a 100 steps, etc. Further key features are limit switch connectors for each motor, encoder connectors, digital sensor inputs and digital/analog outputs.
The CAN interface offers reliable high performance communication with other devices such as Monsterrhino Motion, Monsterrhino Control, Raspberry Pi, Arduino and many more.
Specs:
It is possible to program various functions on the Motion, this enables a fully autonomous and dynamic system.
The main structure of the code consists of six “UserFunction” files (User_Function1.cpp) and the main file (“monsterrhinostep.ino”).
The following image shows you the main structure of the files used to program the Motion:
Note: The loop function is not used, because all processes and actions are programmed in the “Userfunctions” that can be executed simultaneously.
This file is used for main initialization.
Example:
#include <Wire.h>
#include "PortIni.h"
void ExtraInit()
{
g_Input1.SetRunRisingFunction(INPUT_RUN_USERFUNCTION_START_2 + 1);
//set Input1 interrupt at rising edge, Start userfunction 2 with parameter par=1
}
//------------------------------------------------------------------------------
void setup() {
// Init IO
g_System.Init(ExtraInit);
ExtraInit();
}
The six “UserFunction”-files can be programmed for any action. They can be started and stopped by inputs, CAN-commands, UART-commands or other userfunctions.
Serial commands:
f1s1
//Start UserFunction1 with parameter par=1
f2s2
//Start UserFunction2 with parameter par=2 (even if function1 is not finished)
f1t
//Stop UserFunction1
Functions to start or stop other UserFunctions are:
TODO
Ramp behaviour (Datasheet TMC5160/A)
Following the ramp behavior you can adjust the parameters:
An example to set these parameters (with the startup values) is shown here.
g_Motor1.SetRampSpeeds(
g_Motor1.GetStartup_RampSpeedsStart(), g_Motor1.GetStartup_RampSpeedsStop(), g_Motor1.GetStartup_RampSpeedsHold()
); //V1,VMAX, VSTOP
g_Motor1.SetAccelerations(
g_Motor1.GetStartup_AccelerationsAMax(), g_Motor1.GetStartup_AccelerationsDMax(), g_Motor1.GetStartup_AccelerationsA1(), g_Motor1.GetStartup_AccelerationsD1()
); //AMAX, DMAX, A1, D1
Note: Value Vstart is default zero.
See also: Serial Motor commands ramp mode (m1rs,m1rc, m1as)
g_Motor1.SetRampMode(MotorClass::RampMode::POSITIONING_MODE);
g_Motor1.SetRampMode(MotorClass::RampMode::VELOCITY_MODE);
g_Motor1.SetRampMode(MotorClass::RampMode::HOLD_MODE);
There are three different ramp modes:
See also: Serial Motor commands ramp mode (m1rm (v,p,h or ?))
This is the normal mode for a stepper motor. These two functions describe the main action that can be programmed:
g_Motor1.SetTargetPosition(200.0);
//Set target position to 200 steps (double value)
g_Motor1.SetMoveRelative(10.0);
//Set target position 10 steps relative from current position
In this mode the motor turns with the maximum speed.
g_Motor1.SetRampMode(MotorClass::RampMode::VELOCITY_MODE)
//Set ramp mode to "VelocityMode"
g_Motor1.SetMaxSpeed(100);
//Set maximum speed to 100 steps/sec
Note: When changed to this mode, max speed is zero. To begin set max speed to a value greather than 0.
In this mode velocity remains unchanged, unless a stop event occurs. If you change velocity after ramp mode was set to hold mode nothing happens.
Motors have many values that are set default after reset.
These values can be set with serial Motor commands or in the code. After you change one of the startup values you need to save the parameters with the serial command “s save”.
The command “m1st ?” returns a list of all parameters.
Serial commands:
m1st sr 100
//Set motor1 startup value of senseResisor to 100 Ohm
s save //System save
In the following list you can find all motor startup values. They can be read or set with these two functions: SetStartup_ or GetStartup_
g_Motor1.SetStartup_SenseResistor(200);
//Set startup value for motor1 senseResistor to 200 Ohms
| Function | Description |
|---|---|
| drvStrength | |
| bbmTime | |
| bbmClks | |
| SenseResistor | Resistor for current measuring in mOhm |
| MotorCurrent | Motor current in mA |
| MotorCurrentReduction | |
| Freewheeling | Reduce motor current to 0mA in standstill |
| Iholddelay | |
| PwmofsInitial | |
| PwmGradInitial | |
| StepperDirection | Direction of stepper motor |
| MotorSteps | Full steps of stepper motor |
| PWMThrsInt | |
| PWMThrs | |
| COOLThrsInt | |
| COOLThrs | |
| HighThrs | |
| HighThrsInt | |
| SWMode | see Limit switch |
| RampMode | see Ramp mode |
| RampMaxSpeed | Vmax (Ramp behavior) |
| RampMaxSpeedInt | Vmax integer (Ramp behavior) |
| RampSpeedsStartInt | Vstart integer (Ramp behavior) |
| RampSpeedsStart | Vstart (Ramp behavior) |
| RampSpeedsHoldInt | V1 integer (Ramp behavior) |
| RampSpeedsHold | V1 (Ramp behavior) |
| RampSpeedsStopInt | Vstop integer (Ramp behavior) |
| RampSpeedsStop | Vstop (Ramp behavior) |
| AccelerationsAMaxInt | Maximal acceleration integer |
| AccelerationsAMax | Maximal acceleration |
| AccelerationsDMaxInt | Maximal deceleration integer |
| AccelerationsDMax | Maximal deceleration |
| AccelerationsA1Int | Initial acceleration integer |
| AccelerationsA1 | Initial acceleration |
| AccelerationsD1Int | Initial deceleration integer |
| AccelerationsD1 | Initial deceleration |
| HomingMode | See parameter “mode” in Homing |
| HomingOffsetInt | Homing offset integer |
| HomingOffset | Homing offset |
| HomingMaxPos | Homing max. position |
| HomingTimeout | Homing timeout |
| HomingSpeed2Int | Homing speed second contact integer |
| HomingSpeed2 | Homing speed second contact |
| HomingDmaxInt | Homing max deceleration integer |
| HomingDmax | Homing max deceleration |
| COOLCONF | |
| EncoderResolution | |
| EncoderAlloweddeviation | |
| EncoderSetup | |
| EncoderInverted |
It is possible to use various types for limit sensing:
Properties for motor limit switch configuration are set with following parameters:
Example:
Serial commands:
m1swm sle 1
//Motor1 stop left enable
m1swm sre 1
//Motor1 stop right enable
m1tp 10000
//Motor turns to targetPos 10000
//if the right limit switch is activated the motor stops (position not reached!)
or
TMC5160_Reg::SW_MODE_Register swMode;
swMode.stop_l_enable = 1;
//stop left enable
swMode.stop_r_enable = 1;
//stop right enable
g_Motor1.SetSW_Mode(swMode);
//set selected options for motor1 swMode
g_Motor1.SetTargetPosition(1000);
//Set target position to 1000
Special functions are stall guard, coolStepping, power stage tuning and stealth chop.
Events provide the machine to react on different actions depending on motor status, user function status, input status and time.
pUserFunction->m_MotorIoEvent.SetOrCondition(MOTORIOEVENT_MOTOR1PosReached);
//TODO: Add other examples
Homing has four main steps:
Homing can be configured with the following parameters:
g_Motor1.m_HomingParameters.mode = 1;
g_Motor1.m_HomingParameters.rampSpeedHold = 200.0;
g_Motor1.m_HomingParameters.homingOffset = 15.0;
Note:
In step 2, if switch is still pressed after 50 steps, this step will repeat.
In step 3, motor turns 100 steps til it reaches the limit switch, otherwise there is a homing error.
The motor gets set in POSITIONING MODE when homing.
Step 4 speed is startup_maxSpeed.
TODO: Latched pos ?
When setting the “MOTOR_FUNCTION_HOMING” start-trigger, the motor begins homing with the pre-selected parameters.
The next command is to keep the motor locked until the homing event is finished.
g_Motor3.MotorFunction_TiggerStart(MOTOR_FUNCTION_HOMING);
pUserFunction->MotorHomingOk(LOCK_MOTOR3, par);
It is also possible to home without limit switches using StallGuard2.
TODO
Interrupts are used to perform an action when the selected input is triggered, either on the falling or rising edge.
The following function can be coded in the ExtraInit-Function (monsterrhinostep.ino). In this case the interrupt is activated after a reset.
g_Input1.SetRunFallingFunction(INPUT_RUN_MOTOR_STOP_1);
Actions: These are the defined values for an action, beginning with INPUT_RUN_:
Note: All combinations are possible when using a motor action.
g_Input1.SetRunFallingFunction(INPUT_RUN_MOTOR_STOP_1);
//Stop motor 1 at falling edge on input 1
g_Input2.SetRunRisingFunction(INPUT_RUN_MOTOR_STOP_2_3_4);
//Stop motor 2,3 and 4 at rising edge on input 2
g_Input3.SetRunRisingFunction(INPUT_RUN_MOTOR_STOP_1_2_3_4);
//Stop motor 1,2,3 and 4 at rising edge on input 3
g_Input4.SetRunFallingFunction(INPUT_RUN_USERFUNCTION_1 + 2);
//Start user function 1 sub 2 (parameter Par=2) at falling edge on input 4
The state of an input can also be read with the digitalRead-function.
if(digitalRead(g_Input1)==1){
Serial.print("Hello world");
}
Example:
//FILE "monsterrhinostep.ino":
void ExtraInit(){
g_Input1.SetRunFallingFunction(INPUT_RUN_MOTOR_STOP_1);
g_Motor1.SetTargetPosition(1000);
return;
}
//FILE "User_Function1.cpp":
uint32_t UserFunction1(uint32_t par, UserFunction* pUserFunction)
g_Motor1.SetTargetPosition(0);
return 1;
}
see also: Input commands
This board offers two main types of communication:
UART is the simplest way to give commands. MonsterrhinoMotion can be controlled directly, out of the box, via UART-communication.
Just open the serial command window and select the following settings and the COM-port of your MonsterrhinoMotion.
After a successful connection with your MonsterrhinoMotion you can send commands as shown here:
Serial communication is possible via USB. The following properties should be set to ensure correct data transfer:
The serial command is build as follows:
function + Nr + subFunction (+optional: value/subFunction2 + value)
m1tp 100 (Motor 1 target point 100 steps)
m3mr 200 (Motor 3 move relative 200 steps)
m2ma 100 (Motor 2 set motor current to 100mA)
m3ma ? (Motor 3 returns motor current in mA)
m2cp ? (MOtor 2 returns current position)
Attention: Motion needs to be in normal mode not boot mode! Led is blinking
| function | subfunction1 | subfunction1 | subfunction2/value |
|---|---|---|---|
| m | tp | targetpos | (value) or (?) |
| m | cp | currentpos | (value) or (?) |
| m | rm | rampmode | v,p,h or (?) |
| m | ms | maxspeed | (value) or (?) |
| m | cs | currentspeed | (?) |
| m | r | register | Controller Register? |
| m | rs | rampspeeds | (3 values: start,stop,hold), (?) for more information |
| m | ac | acceleration | (value) for A1,Amax,D1,Dmax, (?) for more information |
| m | as | accelerations( | (5 values: A1,D1,hold,Amax,Dmax), (?) for more information |
| m | s | stop | (value) TODO: no output in serial and afterwards problems |
| m | en | enable | (value) or (?) |
| m | ep | encoderposition | TODO |
| m | lp | latchedposition | TODO |
| m | le | latchedencoder | TODO |
| m | mr | moverelative | (value) |
| m | mds | motordrvstatus | (?), other functions to set/get drive status |
| m | mrs | motorrampstat | (?), other functions to set/get ramp status |
| m | gs | gstat | (?), other functions |
| m | ma | currentma | (value) or (?) |
| m | fwm | freewheelingmode | 1,0 or (?) |
| m | mcs | modechangespeeds | (3 values: pwmThrs, coolThrs, highThrs) |
| m | swm | swmode | (?), other functions with value afterwards (s.a. LimitSW section) |
| m | cc | coolconf | (?), other functions |
| m | smp | savemotorparameter | - |
| m | iv | icversion | (?) |
| m | ld | load | default or defaultall TODO:? |
| m | st | startup | (?), other functions to set/get startup values |
| m | ho | homing | (?), other functions to set/get homing values |
| m | tsc | tunesteathchop | - |
| m | tps | tunestallguard | - |
| function | subfunction1 | subfunction1 | subfunction2 |
|---|---|---|---|
| i | if | inputfunction | |
| i | st | startup |
| function | subfunction1 | subfunction1 | subfunction2 |
|---|---|---|---|
| s | sv | softwareversion | (?) |
| s | hv | hardwareversion | (?) |
| s | do | door | TODO |
| s | bi | bordid | (?) according to SW2, binary [0-3] |
| s | ft | firmwaredaytime | (?) return compile time |
| s | st | startup | (?), other functions to set/get startup system values |
| s | pw | pwm +[AnalogPort] | (value) [0-255] |
| s | pf | pwmfrequency + [Aport] | (value) |
| s | sv | save | - |
| s | reset | reboot | - |
| s | ca | canadress | (value) |
| s | cs | canspeed | (value) |
| s | ld | load | - |
| s | d | debug | - |
CAN is a commonly used communication system in automotive, automation and others.
Due to its high reliability and higher speed than UART it can be used to communicate with the Motion from another Motion or, as an example, a RaspberryPi or Arduino (with their CAN-module).
Up to 4 Monsterrhino boards can be connected via CAN to communicate with each other. It is also possible to connect other devices that support CAN communication.
CAN functions can be used in user functions as following:
pUserFunction->RemoteCommand_Motor_SetTargetPosition(3, 1, 200);
//Set target position of motor 1 on board with address 3 to value 200
//address: 3; motorNr:1; Value:200
pUserFunction->RemoteCommand_UserFunction_SetStart(2, 2, 1);
//Start user function 2 sub function 2 on board with address 2
//address: 2; functionNr:2; subFunction:1
uint32_t testVariable = 0;
pUserFunction->RemoteCommand_UserFunction_GetVariable(4, 1, 5, testVariable);
//Get user function variable 5 of user function 1 on board with address 4 and write to testVariable
//address: 5; functionNr:1; functionVar:5; testVariable: variable with return value
The remoteCommand function supports all serial command functions.
In addition you can get and set user function variables via remoteCommand as shown above.
Switch 1 (SW1, CAN TERM) activates CAN termination resistor (120 Ohm) (1 is active).
Switch 2 (SW2, BOARD ID) indicates CAN address (BoardID+2) as follows:
| SW2_1 | SW2_2 | Address | Board ID |
|---|---|---|---|
| LOW | LOW | 2 | 0 |
| HIGH | LOW | 3 | 1 |
| LOW | HIGH | 4 | 2 |
| HIGH | HIGH | 5 | 3 |
Note:
Address 0 is reserved for a broadcast message.
Address 1 is reserved for other devices.
Each User Function has a total of 12 public variables with two types (uint32, double) each 6. These variables have the ability to be read and/or be set over CAN communication.
This variables can be used in CAN-communication.
pUserFunction->m_variable[0] = 0; //m_variable[0]=0 of current UserFunction
pUserFunction->m_variableFloat[4] = 3.45;
Note: m_variable[6] is no variable because each Userfunction offers six of each type.
0-5 equals a total of 6.